package Test;


import static org.junit.Assert.assertTrue;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import Dispatcher.*;

public class DispatcherConcurrency {
	
	private static GroupDispatcher dispatcher;
	

	//receive these kind of messages
	static final int RECEIVED_INIT = 1;
	static final int RECEIVED_UPDATE = 4;
	static final int ELEVATOR_COUNT = 5;

	//create the group dispatcher
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		dispatcher = new GroupDispatcher();
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
//		dispatcher.finalize();
	}
	
	@Test
	public void testRegisterElevators(){
		dispatcher.activateSocket();
		for(int i = 0; i < 5; i++){
			String msg = dispatcher.receiveMessage();
			byte[] bMsg = msg.getBytes();
			
			assertTrue(bMsg[0] == RECEIVED_INIT);
			assertTrue((int)bMsg[1] > 0);
			HandleReceivedMsgThread hrm = new HandleReceivedMsgThread(dispatcher, msg);
			hrm.start();
			try {
				hrm.join();
			} catch (InterruptedException e) {
				System.out.println("Interrupted while joining");
			}	
		}
		assertTrue(dispatcher.getElevators().size() >0);
	}
		
	@Test
	public void testReceiveUpdate(){
		for(int i = 0; i < 5; i++){
			String msg = dispatcher.receiveMessage();
			byte[] bMsg = msg.getBytes();
			assertTrue(bMsg[0] == RECEIVED_UPDATE);
			assertTrue((int)bMsg[1] > 0);
			HandleReceivedMsgThread hrm = new HandleReceivedMsgThread(dispatcher, msg);
			hrm.start();
			try {
				hrm.join();
			} catch (InterruptedException e) {
				System.out.println("Interrupted while joining");
			}
		}
		assertTrue(dispatcher.getStatus().size() > 0);
	}
	
	@Test
	public void testHallCall() throws InterruptedException{
		dispatcher.processHallCall(10, 1);
		dispatcher.processHallCall(2, -1);
		dispatcher.processHallCall(4, 1);
		dispatcher.processHallCall(6, -1);
		dispatcher.processHallCall(8, 1);
	}
	
	@Test
	public void testThreadConcurrency() {
		System.out.println("\n\n");
		
		dispatcher.processHallCall(2, 1);
		String msg = dispatcher.receiveMessage();
		byte[] bMsg = msg.getBytes(); bMsg[0] = 4;
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		HandleReceivedMsgThread hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		dispatcher.processHallCall(6, -1);
		 msg = dispatcher.receiveMessage();
		 bMsg = msg.getBytes(); bMsg[0] = 4;
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		 hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		dispatcher.processHallCall(5, 1);
		 msg = dispatcher.receiveMessage();
		 bMsg = msg.getBytes(); bMsg[0] = 4;
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		 hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		dispatcher.processHallCall(8, -1);
		 msg = dispatcher.receiveMessage();
		 bMsg = msg.getBytes(); bMsg[0] = 4;
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		 hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
		dispatcher.processHallCall(3, 1);
		 msg = dispatcher.receiveMessage();
		 bMsg = msg.getBytes(); bMsg[0] = 4;
		assertTrue(bMsg[0] == RECEIVED_UPDATE);
		assertTrue((int)bMsg[1] > 0);
		 hrm = new HandleReceivedMsgThread(dispatcher, msg);
		hrm.start();
		try {
			hrm.join();
		} catch (InterruptedException e) {
			System.out.println("Interrupted while joining");
		}
	}

}
